package com.allenkerr.service.impl;

import com.allenkerr.dao.PersonRepository;
import com.allenkerr.model.Person;
import com.allenkerr.service.IPersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.util.Optional;
import java.util.concurrent.Future;

import static com.allenkerr.constant.RedisKey.REDIS_KEY_PERSON_CACHE;

/**
 * @author 小柯
 * @date 2017/12/5
 */
@Service
public class PersonServiceImpl implements IPersonService {

  @Autowired
  private PersonRepository personDao;

  @Override
  @Transactional(rollbackFor = Exception.class)
  public Person savePerson(Person person) {
    return personDao.save(person);
  }

  @Override
//  @CachePut(cacheNames = "person", key = "#uuid")
//  @Cacheable(cacheNames = "person-caches", key = "'person-cache:' + #uuid")
  @Cacheable(cacheNames = REDIS_KEY_PERSON_CACHE, key = "#uuid")
  public Person findPersonByUuid(String uuid) {
    return personDao.findFirstByUuid(uuid);
  }

  @Override
  @CacheEvict(cacheNames = "person-caches", key = "#{T(com.allenkerr.constant.RedisKey).REDIS_KEY_PERSON_CACHE + uuid}")
  public Person updatePersonByUuid(String uuid) {
    Person person = personDao.findFirstByUuid(uuid);
    person.setPassword(Instant.now().toString());
    return personDao.save(person);
  }

  @Override
  public Optional<Person> findPersonById(Integer id) {
    return personDao.findById(id);
  }

  @Async
  @Override
  public Future<Person> asyncFindPersonByUuid(String uuid) {
    Person person = personDao.findFirstByUuid(uuid);
    return new AsyncResult<>(person);
  }

}
